package com.chentu.aliyun.oss.service.impl;

import com.aliyun.oss.*;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.chentu.aliyun.oss.properties.OssProperties;
import com.chentu.aliyun.oss.service.IOssClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * Author: LiZhong Wang
 * <p> DateTime: 2024/9/24 10:37
 * <p> Description:
 * <p>
 **/
@Slf4j
@Component("aliyunOssClient")
public class AliyunOssClient implements IOssClient {
	
	
	private static OSS client;
	private final OssProperties properties;
	private static final String HTTPS_PREFIX = "https://";
	
	public AliyunOssClient(OssProperties properties) {
		if (properties.getEndpoint().contains(AliyunOssClient.HTTPS_PREFIX)) {
			properties.setEndpoint(properties.getEndpoint().replace(AliyunOssClient.HTTPS_PREFIX, ""));
		}
		this.properties = properties;
		OSS client = null;
		// 初始化aliyun oss 配置
		ClientConfiguration clientConfiguration = new ClientBuilderConfiguration();
		clientConfiguration.setMaxConnections(properties.getMaxConnections());
		clientConfiguration.setConnectionTimeout(properties.getConnectionTimeout());
		clientConfiguration.setMaxErrorRetry(properties.getMaxErrorRetry());
		clientConfiguration.setSocketTimeout(properties.getSocketTimeout());
		clientConfiguration.setSupportCname(properties.getSupportCname());
		clientConfiguration.setUserAgent(properties.getUserAgent());
		clientConfiguration.setIdleConnectionTime(properties.getIdleConnectionTime());
		clientConfiguration.setVerifySSLEnable(properties.getVerifySSLEnable());
		
		try {
			log.info("开始加载初始化OSS对象");
			client = new OSSClientBuilder().build(AliyunOssClient.HTTPS_PREFIX + properties.getEndpoint(), properties.getAccessKey(), properties.getSecretKey());
			log.info("OSS对象初始化成功");
		} catch (Exception e) {
			log.error("OSS对象初始化失败, 错误原因为: {}", e.getMessage());
		}
		
		AliyunOssClient.client = client;
	}
	
	/**
	 * 上传文件到 oss
	 *
	 * @param ossFilePath   oss文件路径 path+文件名.suffix  eg: test/test.jpg
	 * @param localFilePath 本地文件路径 eg: /home/test/test.jpg
	 * @return true 成功
	 * @tip 阿里oss规范, oss路径不得以/开头
	 */
	@Override
	public String upload(String ossFilePath, String localFilePath) {
		try {
			log.info("开始上传文件: ossFilePath:{},localFilePath:{}", ossFilePath, localFilePath);
			PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), ossFilePath, Files.newInputStream(Paths.get(localFilePath)));
			client.putObject(putObjectRequest);
			log.info("文件上传成功");
		} catch (Exception e) {
			log.error("上传文件失败", e);
			throw new OSSException("文件上传失败");
		}
		return AliyunOssClient.HTTPS_PREFIX + properties.getBucketName() + "." + properties.getEndpoint() + "/" + ossFilePath;
	}
	
	/**
	 * 上传文件到 oss
	 *
	 * @param ossFilePath oss文件路径 path+文件名.suffix  eg: test/test.jpg
	 * @param bytes       上传文件字节数组
	 * @return true 成功
	 * @tip 阿里oss规范, oss路径不得以/开头
	 */
	@Override
	public String upload(String ossFilePath, byte[] bytes) {
		try {
			log.info("开始上传文件到: ossFilePath:{}", ossFilePath);
			PutObjectResult putObjectResult = client.putObject(properties.getBucketName(), ossFilePath, new ByteArrayInputStream(bytes));
			log.info("文件上传成功");
		} catch (Exception e) {
			log.error("上传文件失败", e);
			throw new OSSException("文件上传失败");
			
		}
		
		return "https://" + properties.getBucketName() + "." + properties.getEndpoint() + "/" + ossFilePath;
	}
	
	/**
	 * 删除文件地址 文件对应全路径 eg: https://bucket.oss-cn-beijing.aliyuncs.com/test/test.jpg
	 *
	 * @param ossFileUrl 文件全地址
	 */
	@Override
	public Boolean delete(String ossFileUrl) {
		try {
			log.info("开始删除文件: ossFileUrl:{}", ossFileUrl);
			String ossFilePath = ossFileUrl.replace(AliyunOssClient.HTTPS_PREFIX + properties.getBucketName() + "." + properties.getEndpoint() + "/", "");
			client.deleteObject(properties.getBucketName(), ossFilePath);
			log.info("文件删除成功");
		} catch (Exception e) {
			log.error("删除文件失败", e);
			return false;
		}
		return true;
	}
	
	@Deprecated
	@Override
	public String getUrl(String fileName) {
		return "";
	}
}
